﻿using ActiproSoftware.Windows.Extensions;
using ArcGIS.Core.Data;
using ArcGIS.Core.Data.DDL;
using ArcGIS.Core.Data.Exceptions;
using ArcGIS.Core.Geometry;
using ArcGIS.Core.Internal.CIM;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Editing;
using ArcGIS.Desktop.Framework.Threading.Tasks;
//using ArcGIS.Desktop.Internal.Core.Assistant.EnterpriseClient.ChatRequest.QueryGenerationTypes;
using ArcGIS.Desktop.Mapping;
using Aspose.Cells.Drawing;
using Aspose.Words.Drawing;
using CCTool.Scripts.Manager;
using CCTool.Scripts.ToolManagers;
using CCTool.Scripts.ToolManagers.Extensions;
using CCTool.Scripts.ToolManagers.Library;
using CCTool.Scripts.ToolManagers.Managers;
using CCTool.Scripts.ToolManagers.Windows;
using CCTool.Scripts.UI.ProWindow;
using Newtonsoft.Json.Linq;
using NPOI.OpenXmlFormats.Shared;
using NPOI.OpenXmlFormats.Vml;
using NPOI.POIFS.Crypt.Dsig;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

using System.Windows.Media;
using CheckBox = System.Windows.Controls.CheckBox;
using MessageBox = ArcGIS.Desktop.Framework.Dialogs.MessageBox;
using Polygon = ArcGIS.Core.Geometry.Polygon;
using SpatialReference = ArcGIS.Core.Geometry.SpatialReference;

namespace CCTool.Scripts.DataPross.TXT
{
    /// <summary>
    /// Interaction logic for BPTXT2GDB.xaml
    /// </summary>
    public partial class BPTXT2GDB : ArcGIS.Desktop.Framework.Controls.ProWindow
    {
        // 工具设置标签
        readonly string toolSet = "BPTXT2GDB";

        public BPTXT2GDB()
        {
            InitializeComponent();

            // 初始化
            textFolderPath.Text = BaseTool.ReadValueFromReg(toolSet, "folderPath");
            textFeatureClassPath.Text = BaseTool.ReadValueFromReg(toolSet, "fcPath");

            // 更新列表框
            UpdataListBox();

        }

        // 定义一个进度框
        private ProcessWindow processwindow = null;
        string tool_name = "报批TXT文件转要素类(批量)";

        private async void btn_go_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 获取指标
                string folderPath = textFolderPath.Text;
                string fcPath = textFeatureClassPath.Text;

                var cb_txts = listbox_txt.Items;

                // 参数写入本地
                BaseTool.WriteValueToReg(toolSet, "folderPath", folderPath);
                BaseTool.WriteValueToReg(toolSet, "fcPath", fcPath);

                // 判断参数是否选择完全
                if (folderPath == "" || fcPath == "" || cb_txts.Count == 0)
                {
                    MessageBox.Show("有必选参数为空！！！");
                    return;
                }

                // 获取所有选中的txt
                List<string> list_txtPath = new List<string>();
                foreach (CheckBox shp in cb_txts)
                {
                    if (shp.IsChecked == true)
                    {
                        list_txtPath.Add(folderPath + shp.Content);
                    }
                }

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                Close();
                // 异步执行
                await QueuedTask.Run(() =>
                {
                    pw.AddMessageStart("检查数据");
                    // 检查数据
                    List<string> errs = CheckData(fcPath, list_txtPath);
                    // 打印错误
                    if (errs.Count > 0)
                    {
                        foreach (var err in errs)
                        {
                            pw.AddMessageMiddle(10, err, Brushes.Red);
                        }
                        return;
                    }

                    pw.AddMessageMiddle(0, "创建空要素类");
                    string gdbPath = fcPath[..(fcPath.LastIndexOf(".gdb") + 4)];
                    string fcName = fcPath[(fcPath.LastIndexOf(@"\") + 1)..];

                    // 获取坐标系
                    SpatialReference sr = GetSR(list_txtPath);
                    // 精度，地理坐标系，需要高精度
                    double xyTol = 0.000000000001;

                    // 创建空要素类
                    Arcpy.CreateFeatureclass(gdbPath, fcName, "POLYGON", sr, XYtol: xyTol, XYres: xyTol/10);

                    // 打开数据库
                    using (Geodatabase gdb = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(gdbPath))))
                    {
                        // 创建要素并添加到要素类中
                        using FeatureClass featureClass = gdb.OpenDataset<FeatureClass>(fcName);

                        // 解析文本并创建要素
                        foreach (var txtPath in list_txtPath)
                        {
                            var mapPoints = new List<Coordinate2D>();

                            // 获取txt文件的文本内容
                            string text = TxtTool.GetTXTContent(txtPath);
                            // 解析JSON字符串
                            JObject jsonObj = JObject.Parse(text);

                            // 读取rings数组
                            JArray ringsArray = (JArray)jsonObj["rings"];
                            if (ringsArray != null && ringsArray.Count > 0)
                            {
                                // 遍历每个ring(外环或内环)
                                List<Polygon> polygons = new List<Polygon>();

                                foreach (JArray ring in ringsArray)
                                {
                                    // 创建点集合
                                    List<MapPoint> points = new List<MapPoint>();

                                    foreach (JArray coord in ring)
                                    {
                                        double x = coord[0].Value<double>();
                                        double y = coord[1].Value<double>();
                                        mapPoints.Add(new Coordinate2D(x, y));
                                    }
                                }
                            }

                            /// 构建面要素
                            // 创建编辑操作对象
                            EditOperation editOperation = new EditOperation();
                            editOperation.Callback(context =>
                            {
                                // 获取要素定义
                                FeatureClassDefinition featureClassDefinition = featureClass.GetDefinition();
                                // 创建RowBuffer
                                using RowBuffer rowBuffer = featureClass.CreateRowBuffer();

                                PolygonBuilderEx pb = new PolygonBuilderEx(mapPoints);

                                // 给新添加的行设置形状
                                rowBuffer[featureClassDefinition.GetShapeField()] = pb.ToGeometry();

                                // 在表中创建新行
                                using Feature feature = featureClass.CreateRow(rowBuffer);
                                context.Invalidate(feature);      // 标记行为无效状态
                            }, featureClass);

                            MapCtlTool.OpenEdit();
                            // 执行编辑操作
                            editOperation.Execute();
                        }
                    }

                    // 保存编辑
                    Project.Current.SaveEditsAsync();

                    // 加载图层
                    MapCtlTool.AddLayerToMap(fcPath);

                    pw.AddMessageEnd();
                });
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }

        }

        // 获取容差
        private double GetXYTol(List<string> list_txtPath)
        {
            double tol = 0;

            foreach (var txtPath in list_txtPath)
            {
                // 获取txt文件的文本内容
                string text = TxtTool.GetTXTContent(txtPath);

                // 解析JSON字符串
                JObject jsonObj = JObject.Parse(text);

                // 读取rings数组
                JArray ringsArray = (JArray)jsonObj["rings"];
                if (ringsArray != null && ringsArray.Count > 0)
                {
                    // 遍历每个ring(外环或内环)
                    foreach (JArray ring in ringsArray)
                    {
                        List<Coordinate2D> ringCoords = new List<Coordinate2D>();
                        foreach (JArray coord in ring)
                        {
                            string x = coord[0].Value<double>().ToString();

                            int x_len = x.Length - x.IndexOf('.') - 1;
                            tol = Math.Pow(0.1, x_len);
                            break;
                        }

                    }
                }
            }
            return tol;
        }


        // 获取坐标系
        private SpatialReference GetSR(List<string> list_txtPath)
        {
            SpatialReference sr = null;

            foreach (var txtPath in list_txtPath)
            {
                // 获取txt文件的文本内容
                string text = TxtTool.GetTXTContent(txtPath);

                // 解析JSON字符串
                JObject jsonObj = JObject.Parse(text);

                // 获取坐标系信息
                if (jsonObj["spatialReference"] != null)
                {
                    int wkid = jsonObj["spatialReference"]["wkid"]?.Value<int>() ?? 0;
                    if (wkid > 0)
                    {
                        sr = SpatialReferenceBuilder.CreateSpatialReference(wkid);
                        break;
                    }
                }
            }
            return sr;
        }

        private void openFeatureClassButton_Click(object sender, RoutedEventArgs e)
        {
            textFeatureClassPath.Text = UITool.SaveDialogFeatureClass();
        }

        private void openSHPButton_Click(object sender, RoutedEventArgs e)
        {
            // 打开TXT文件夹
            textFolderPath.Text = UITool.OpenDialogFolder();
            // 更新列表框的内容
            UpdataListBox();
        }

        // 更新列表框的内容
        private void UpdataListBox()
        {
            string folder = textFolderPath.Text;
            // 清除listbox
            listbox_txt.Items.Clear();
            // 生成TXT要素列表
            if (folder != "" && Directory.Exists(folder))
            {
                // 获取所有shp文件
                var files = DirTool.GetAllFiles(folder, ".txt");
                foreach (var file in files)
                {
                    // 将txt文件做成checkbox放入列表中
                    CheckBox cb = new CheckBox();
                    cb.Content = file.Replace(folder, "");
                    cb.IsChecked = true;
                    listbox_txt.Items.Add(cb);
                }
            }
        }

        // 文本中的【@】符号放前
        public static string ChangeSymbol(string text)
        {
            string[] lins = text.Split('\n');
            string updata_lins = "";
            foreach (string line in lins)
            {

                if (line.Contains("@"))
                {
                    string newline = line.Replace("@", "");
                    newline = "@" + newline;
                    updata_lins += newline + "\n";
                }
                else
                {
                    updata_lins += line + "\n";
                }
            }
            return updata_lins;
        }

        // 获取指标
        public static Dictionary<string, string> GetAtt(string text)
        {
            Dictionary<string, string> dict = new Dictionary<string, string>();
            string new_text = text[text.IndexOf("[项目信息]")..text.IndexOf("[属性描述]")];
            string[] lines = new_text.Split("\n");
            foreach (string line in lines)
            {
                if (line.Contains('='))
                {
                    string before = line[..line.IndexOf("=")];
                    string after = line[(line.IndexOf("=") + 1)..];
                    dict.Add(before, after);
                }
            }
            return dict;
        }

        // 获取要素的部件数
        public static int GetCount(string lines)
        {
            List<string> indexs = new List<string>();

            // 根据换行符分解坐标点文本
            string[] list_point = lines.Split("\n");

            foreach (var point in list_point)
            {
                if (TxtTool.StringInCount(point, ",") == 3)          // 点坐标文本
                {
                    // 判断是否带空洞
                    string fid = point.Split(",")[1];        // 图斑部件号
                    if (!indexs.Contains(fid))
                    {
                        indexs.Add(fid);
                    }
                }
                else    // 路过非点坐标文本
                {
                    continue;
                }
            }

            return indexs.Count;
        }

        private void downLoadButton_Click(object sender, RoutedEventArgs e)
        {
            string url = "https://pan.baidu.com/s/1KsCdwfIMOS61G6kHHO_SgQ?pwd=9kri";
            UITool.Link2Web(url);
        }

        private List<string> CheckData(string featurePath, List<string> txtFiles)
        {
            List<string> result = new List<string>();

            // 判断输出路径是否为gdb
            string gdbRusult = CheckTool.CheckGDBFeature(featurePath);
            if (gdbRusult != "")
            {
                result.Add(gdbRusult);
            }

            // 检查txt文件合规性
            foreach (string txtPath in txtFiles)
            {
                string shp_name_old = txtPath[(txtPath.LastIndexOf(@"\") + 1)..].Replace(".txt", "");  // 获取要素名
                // 预处理一下要素名，避免一些奇奇怪怪的符号
                string shp_name = shp_name_old.Replace(".", "_");

                // 获取txt文件的文本内容
                string text = TxtTool.GetTXTContent(txtPath);
                // 文本中的【@】符号放前
                string updata_text = ChangeSymbol(text);

                // 获取坐标点文本
                string[] fcs_text = updata_text.Split("@");
                // 去除第一部分非坐标文本
                List<string> fcs_text2List = new List<string>(fcs_text);
                fcs_text2List.RemoveAt(0);

                // 一个文件可能有多要素
                foreach (var txt in fcs_text2List)
                {
                    // 根据换行符分解坐标点文本
                    string[] list_point = txt.Split("\n");

                    foreach (var point in list_point)
                    {
                        if (TxtTool.StringInCount(point, ",") > 3)     // 名称、地块编号、功能文本
                        {
                            if (TxtTool.StringInCount(point, ",") != 8)
                            {
                                result.Add($"【{shp_name}】错误行：{point}");
                            }
                        }
                    }
                }
            }

            return result;
        }

        private void btn_help_Click(object sender, RoutedEventArgs e)
        {
            string url = "https://blog.csdn.net/xcc34452366/article/details/140745629";
            UITool.Link2Web(url);
        }

        private void btn_select_Click(object sender, RoutedEventArgs e)
        {
            UITool.SelectListboxItems(listbox_txt);
        }

        private void btn_unSelect_Click(object sender, RoutedEventArgs e)
        {
            UITool.UnSelectListboxlItems(listbox_txt);
        }

    }
}
